/**
 * @param {*} type  转换的类型
 * 					type=1	返回yyyy-mm-dd
 * 					type=2  返回yyyy-mm-dd hh
 * 					type=3  返回yyyy-mm-dd hh:mm
 * 					type=4  返回yyyy-mm-dd hh:mm:ss
 * 					type=5	返回yyyy/mm/dd
 * 					type=6	返回yyyy/mm/dd hh
 * 					type=7	返回yyyy/mm/dd hh:mm
 * 					type=8	返回yyyy/mm/dd hh:mm:ss
 * 					type=9	返回yyyymmdd
 * 					type=10	返回yyyymmdd hh
 * 					type=11	返回yyyymmdd hh:mm
 * 					type=12	返回yyyymmdd hh:mm:ss
 * 					type=13	返回本地时间(中文版浏览器为"2013年1月1日 上午12:00:00" ，英文版浏览器为"1/1/2013 12:00:00 AM"
 * 					type=14	返回本地时间(中文版浏览器为"2013年1月1日"，英文版浏览器为"1/1/2013"
 * 					type=15	返回本地时间(中文版浏览器为"上午12:00:00"，英文版浏览器为"12:00:00 AM"
 * 					type=16	返回时间戳
 * 					type=17	返回星期几
 * 					type=18	返回农历
 * 					type=19	返回节气
 * 					type=20	返回即时（秒/分/小时/天/月/年前）
 * 					type=21	返回生肖
 * 					type=22	返回每天的某个阶段（上午，下午......）
 * 					type=23	返回公历节假日
 * 					type=24	返回农历节假日
 * @param {*} timer 原时间对象||可转换时间对象的字符串 || 时间戳
 * 					'Aug 9, 1995'
 *					'January 26, 2011 13:51:50'
 *					'Mon, 25 Dec 1995 13:30:00 GMT'
 *					'Mon, 25 Dec 1995 13:30:00 +0430'
 *					'2011-10-10'
 *					'2011-10-10T14:48:00'
 *					'20211101'
*/

export function TimeConversion({ type = 1, timer = '' } = {}) {
	let TimerObject = null
	if (timer) {
		if (new Date(timer).toDateString() === "Invalid Date") {
			if (dataType(timer) === 'String' && parseInt(timer) && timer.trim().length === 8) {
				timer = timer.replace(/年/g, '/')
				timer = timer.replace(/月/g, '/')
				timer = timer.replace(/日/g, '')
				timer = timer.replace(/时/g, ':')
				timer = timer.replace(/分/g, ':')
				timer = timer.replace(/秒/g, '')
				const str = `${timer.substring(0, 4)}-${timer.substring(4, 6)}-${timer.substring(6, 8)}`
				if (new Date(str).toDateString() !== "Invalid Date") {
					TimerObject = new Date(str)
				} else {
					TimerObject = new Date()
				}
			} else {
				TimerObject = new Date()
			}
		} else {
			TimerObject = new Date(timer)
		}
	} else {
		TimerObject = new Date()
	}
	// 年
	const y = TimerObject.getFullYear()
	// 月
	const m = strLength(TimerObject.getMonth() + 1)
	// 日
	const d = strLength(TimerObject.getDate())
	// 时
	const h = strLength(TimerObject.getHours())
	// 分
	const mm = strLength(TimerObject.getMinutes())
	// 秒
	const ss = strLength(TimerObject.getSeconds())
	// 星期
	const day = `星期${dayFunc(TimerObject.getDay())}`
	// 时间戳
	const ms = TimerObject.getTime()
	if (type === 1) {
		return `${y}-${m}-${d}`
	} else if (type === 2) {
		return `${y}-${m}-${d} ${h}`
	} else if (type === 3) {
		return `${y}-${m}-${d} ${h}:${mm}`
	} else if (type === 4) {
		return `${y}-${m}-${d} ${h}:${mm}:${ss}`
	} else if (type === 5) {
		return `${y}/${m}/${d}`
	} else if (type === 6) {
		return `${y}/${m}/${d} ${h}`
	} else if (type === 7) {
		return `${y}/${m}/${d} ${h}:${mm}`
	} else if (type === 8) {
		return `${y}/${m}/${d} ${h}:${mm}:${ss}`
	} else if (type === 9) {
		return `${y}${m}${d}`
	} else if (type === 10) {
		return `${y}${m}${d} ${h}`
	} else if (type === 11) {
		return `${y}${m}${d} ${h}:${mm}`
	} else if (type === 12) {
		return `${y}${m}${d} ${h}:${mm}:${ss}`
	} else if (type === 13) {
		return `${y}年${parseInt(m)}月${parseInt(d)}日 ${TimerObject.toLocaleString().split(' ')[1]}`
	} else if (type === 14) {
		return `${y}年${parseInt(m)}月${parseInt(d)}日`
	} else if (type === 15) {
		return `${TimerObject.toLocaleString().split(' ')[1]}`
	} else if (type === 16) {
		return ms
	} else if (type === 17) {
		return day
	} else if (type === 18) {
		const msg = TimerObject.toLocaleString('ja-JP-u-ca-chinese').toLocaleString().split(' ')[0]
		const year = msg.substring(0, msg.indexOf('年'))
		const moon = lunarMonth(parseInt(msg.split('月')[0].replace(/[^\d]/g, "")))
		const day = lunarCalendar(parseInt(msg.split('月')[1].replace(/[^\d]/g, "")))
		return `${year}年${moon}月${day}`
	} else if (type === 19) {
		return getSolarTerm(y, m, d)
	} else if (type === 20) {
		return immediate(TimerObject)
	} else if (type === 21) {
		return ChineseZodiac(y)
	} else if (type === 22) {
		return DayStage(Number(h))
	} else if (type === 23) {
		return GregorianHolidays(m, d)
	} else if (type === 24) {
		return getLunarCalendar(y, m, d)
	}
	return `${y}-${m}-${d}`
}

// 计算节气, sy sm sd 为传入年月日
function getSolarTerm(sy: number, sm: string, sd: string) {
	const solarTermInfo = new Array(
		0, 1272480000, 2548020000, 3830160000, 5120220000, 6420840000,
		7732020000, 9055260000, 10388940000, 11733060000, 13084320000, 14441580000,
		15800580000, 17159340000, 18513780000, 19861980000, 21201000000, 22529640000,
		23846820000, 25152600000, 26447700000, 27733440000, 29011920000, 30285480000
	);
	const solarTerm = new Array(
		"小寒", "大寒", "立春", "雨水", "惊蛰", "春分",
		"清明", "谷雨", "立夏", "小满", "芒种", "夏至",
		"小暑", "大暑", "立秋", "处暑", "白露", "秋分",
		"寒露", "霜降", "立冬", "小雪", "大雪", "冬至"
	);
	sm -= 1;
	let solarTermStr = "";
	//月份乘2是因为每月平均2节气对应二十四节气加一考虑存在闰月
	let tmp1 = new Date((31556925974.7 * (sy - 1900) + solarTermInfo[sm * 2 + 1]) + Date.UTC(1900, 0, 6, 2, 5));
	let tmp2 = tmp1.getUTCDate();
	if (tmp2 == sd) solarTermStr = solarTerm[sm * 2 + 1];
	tmp1 = new Date((31556925974.7 * (sy - 1900) + solarTermInfo[sm * 2]) + Date.UTC(1900, 0, 6, 2, 5));
	tmp2 = tmp1.getUTCDate();
	if (tmp2 == sd) solarTermStr = solarTerm[sm * 2];
	if (sd > 1) {
		sd -= 1;
	}
	else {
		sm -= 1;
		sd = 31;
		if (sm < 0) {
			sy -= 1;
			sm = 11;
		}
	}
	return solarTermStr;
}

// 判断数据类型
function dataType(msg: any) {
	return toString.call(msg).substring(8, toString.call(msg).length - 1)
}

// 返回星期几
function dayFunc(params: number) {
	const list = [
		{ key: 1, value: '一' },
		{ key: 2, value: '二' },
		{ key: 3, value: '三' },
		{ key: 4, value: '四' },
		{ key: 5, value: '五' },
		{ key: 6, value: '六' },
		{ key: 0, value: '天' }
	]
	return list.find(item => item.key === params)?.value || ''
}

// 补全长度
function strLength(params: number) {
	return `${params}`.length > 1 ? `${params}` : `0${params}`
}

// 返回农历月
function lunarMonth(key: number) {
	const moonList = [
		{ key: 1, value: '正' },
		{ key: 2, value: '二' },
		{ key: 3, value: '三' },
		{ key: 4, value: '四' },
		{ key: 5, value: '五' },
		{ key: 6, value: '六' },
		{ key: 7, value: '七' },
		{ key: 8, value: '八' },
		{ key: 9, value: '九' },
		{ key: 10, value: '十' },
		{ key: 11, value: '冬' },
		{ key: 12, value: '腊' },
	]
	return moonList.find(item => item.key === key) ? moonList.find(item => item.key === key)?.value || '' : ''
}

// 返回农历初几
function lunarCalendar(key: number) {
	const dayList = [
		{ key: 1, value: '初一' },
		{ key: 2, value: '初二' },
		{ key: 3, value: '初三' },
		{ key: 4, value: '初四' },
		{ key: 5, value: '初五' },
		{ key: 6, value: '初六' },
		{ key: 7, value: '初七' },
		{ key: 8, value: '初八' },
		{ key: 9, value: '初九' },
		{ key: 10, value: '初十' },
		{ key: 11, value: '十一' },
		{ key: 12, value: '十二' },
		{ key: 13, value: '十三' },
		{ key: 14, value: '十四' },
		{ key: 15, value: '十五' },
		{ key: 16, value: '十六' },
		{ key: 17, value: '十七' },
		{ key: 18, value: '十八' },
		{ key: 19, value: '十九' },
		{ key: 20, value: '二十' },
		{ key: 21, value: '廿一' },
		{ key: 22, value: '廿二' },
		{ key: 23, value: '廿三' },
		{ key: 24, value: '廿四' },
		{ key: 25, value: '廿五' },
		{ key: 26, value: '廿六' },
		{ key: 27, value: '廿七' },
		{ key: 28, value: '廿八' },
		{ key: 29, value: '廿九' },
		{ key: 30, value: '三十' }
	]
	return dayList.find(item => item.key === key) ? dayList.find(item => item.key === key)?.value || '' : ''
}

// 返回即时时间与当前差时
function immediate(msg: any) {
	if (msg && new Date(msg).toDateString() !== 'Invalid Date') {
		const moon = new Date(msg).getMonth() // 判断是否当月
		const year = new Date().getFullYear() - new Date(msg).getFullYear()

		const current = new Date().getTime() - new Date(msg).getTime()
		const Minutes = 60 * 1000 // 1分时间戳
		const Hours = 60 * 60 * 1000 // 1小时时间戳
		const sky = 24 * 60 * 60 * 1000 // 1天时间戳
		const Month = 30 * 24 * 60 * 60 * 1000 // 1月时间戳
		const therMonth = 3 * 30 * 24 * 60 * 60 * 1000 // 3月时间戳
		const SixMonths = 6 * 30 * 24 * 60 * 60 * 1000 // 半年时间戳
		const twelveMonths = 12 * 30 * 24 * 60 * 60 * 1000 // 一年时间戳
		if (year === 0) {
			if (current < twelveMonths && current >= SixMonths) {
				return `半年前`
			}
			if (current < SixMonths && current >= therMonth) {
				return `三个月前`
			}
			if (current < therMonth && current >= Month) {
				return `一个月前`
			}
			if (current < Month) {
				// 当月
				if (current <= sky) {
					// 当天
					if (current <= Minutes) {
						const s = new Date().getTime() - new Date(msg).getTime()
						return `${Math.round(s / 1000)}秒前`
					} else if (current <= Hours) {
						const m = new Date().getTime() - new Date(msg).getTime()
						return `${Math.round(m / Minutes)}分前`
					} else {
						const h = new Date().getTime() - new Date(msg).getTime()
						return `${Math.round(h / Hours)}小时前`
					}
				} else {
					return `${Math.round((new Date().getTime() - new Date(msg).getTime()) / sky)}天前`
				}
			}
		} else if (year === 1) {
			if (moon > new Date().getMonth()) {
				if ((new Date().getMonth() === 0 && [10, 11].includes(moon)) || (new Date().getMonth() === 1 && [11].includes(moon))) {
					return `一个月前`
				} else if (
					(new Date().getMonth() === 2 && [11].includes(moon)) ||
					(new Date().getMonth() === 1 && [10].includes(moon)) ||
					(new Date().getMonth() === 0 && [9].includes(moon))
				) {
					return `三个月前`
				} else {
					return `半年前`
				}
			} else {
				return `${year}年前`
			}
		} else {
			if (year) {
				return `${year}年前`
			} else {
				return `${Math.abs(year)}年后`
			}
		}
	} else {
		return '刚刚'
	}
}

// 返回生肖
function ChineseZodiac(year: number) {
	const list = ['猴', '鸡', '狗', '猪', '鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊']
	return list[year % 12]
}

// 返回每天阶段
function DayStage(hour: number) {
	if (hour < 6) {
		return "凌晨";
	} else if (hour < 9) {
		return "早上";
	} else if (hour < 12) {
		return "上午";
	} else if (hour < 14) {
		return "中午";
	} else if (hour < 17) {
		return "下午";
	} else if (hour < 19) {
		return "傍晚";
	} else {
		return "晚上";
	}
}

// 返回公里节假日
function GregorianHolidays(m: string, d: string) {
	const list = [
		{ date: "0101", msg: "元旦" },
		{ date: "0214", msg: "情人节" },
		{ date: "0307", msg: "女生节" },
		{ date: "0308", msg: "妇女节" },
		{ date: "0312", msg: "植树节" },
		{ date: "0401", msg: "愚人节" },
		{ date: "0404", msg: "清明节" },
		{ date: "0501", msg: "劳动节" },
		{ date: "0504", msg: "青年节" },
		{ date: "0601", msg: "儿童节" },
		{ date: "0701", msg: "建党节" },
		{ date: "0801", msg: "建军节" },
		{ date: "0910", msg: "教师节" },
		{ date: "1001", msg: "国庆节" },
		{ date: "1031", msg: "万圣节" },
		{ date: "1224", msg: "平安夜" },
		{ date: "1225", msg: "圣诞节" },
	];
	return list.find(item => item.date === `${m}${d}`) ? list.find((item) => item.date === `${m}${d}`)?.msg || '' : ''
}

/*******************************************************************************/
// 以下代码判断农历节假日
/*******************************************************************************/
const lunarInfo = new Array(
	0x4bd8, 0x4ae0, 0xa570, 0x54d5, 0xd260, 0xd950, 0x5554, 0x56af, 0x9ad0, 0x55d2,
	0x4ae0, 0xa5b6, 0xa4d0, 0xd250, 0xd255, 0xb54f, 0xd6a0, 0xada2, 0x95b0, 0x4977,
	0x497f, 0xa4b0, 0xb4b5, 0x6a50, 0x6d40, 0xab54, 0x2b6f, 0x9570, 0x52f2, 0x4970,
	0x6566, 0xd4a0, 0xea50, 0x6a95, 0x5adf, 0x2b60, 0x86e3, 0x92ef, 0xc8d7, 0xc95f,
	0xd4a0, 0xd8a6, 0xb55f, 0x56a0, 0xa5b4, 0x25df, 0x92d0, 0xd2b2, 0xa950, 0xb557,
	0x6ca0, 0xb550, 0x5355, 0x4daf, 0xa5b0, 0x4573, 0x52bf, 0xa9a8, 0xe950, 0x6aa0,
	0xaea6, 0xab50, 0x4b60, 0xaae4, 0xa570, 0x5260, 0xf263, 0xd950, 0x5b57, 0x56a0,
	0x96d0, 0x4dd5, 0x4ad0, 0xa4d0, 0xd4d4, 0xd250, 0xd558, 0xb540, 0xb6a0, 0x95a6,
	0x95bf, 0x49b0, 0xa974, 0xa4b0, 0xb27a, 0x6a50, 0x6d40, 0xaf46, 0xab60, 0x9570,
	0x4af5, 0x4970, 0x64b0, 0x74a3, 0xea50, 0x6b58, 0x5ac0, 0xab60, 0x96d5, 0x92e0,
	0xc960, 0xd954, 0xd4a0, 0xda50, 0x7552, 0x56a0, 0xabb7, 0x25d0, 0x92d0, 0xcab5,
	0xa950, 0xb4a0, 0xbaa4, 0xad50, 0x55d9, 0x4ba0, 0xa5b0, 0x5176, 0x52bf, 0xa930,
	0x7954, 0x6aa0, 0xad50, 0x5b52, 0x4b60, 0xa6e6, 0xa4e0, 0xd260, 0xea65, 0xd530,
	0x5aa0, 0x76a3, 0x96d0, 0x4afb, 0x4ad0, 0xa4d0, 0xd0b6, 0xd25f, 0xd520, 0xdd45,
	0xb5a0, 0x56d0, 0x55b2, 0x49b0, 0xa577, 0xa4b0, 0xaa50, 0xb255, 0x6d2f, 0xada0,
	0x4b63, 0x937f, 0x49f8, 0x4970, 0x64b0, 0x68a6, 0xea5f, 0x6b20, 0xa6c4, 0xaaef,
	0x92e0, 0xd2e3, 0xc960, 0xd557, 0xd4a0, 0xda50, 0x5d55, 0x56a0, 0xa6d0, 0x55d4,
	0x52d0, 0xa9b8, 0xa950, 0xb4a0, 0xb6a6, 0xad50, 0x55a0, 0xaba4, 0xa5b0, 0x52b0,
	0xb273, 0x6930, 0x7337, 0x6aa0, 0xad50, 0x4b55, 0x4b6f, 0xa570, 0x54e4, 0xd260,
	0xe968, 0xd520, 0xdaa0, 0x6aa6, 0x56df, 0x4ae0, 0xa9d4, 0xa4d0, 0xd150, 0xf252, 0xd520);

//判断y年的农历中那个月是闰月
function leapMonth(y: number) {
	let lm = lunarInfo[y - 1900] & 0xf;
	return (lm == 0xf ? 0 : lm);
}

//返回农历y年m月的总天数
function monthDays(y: number, m: number) {
	return ((lunarInfo[y - 1900] & (0x10000 >> m)) ? 30 : 29);
}

//返回农历y年闰月的天数
function leapDays(y) {
	if (leapMonth(y)) {
		return ((lunarInfo[y - 1899] & 0xf) == 0xf ? 30 : 29);
	} else {
		return (0);
	}
}

//返回农历y年的总天数
function lYearDays(y: number) {
	let i, sum = 348;
	for (i = 0x8000; i > 0x8; i >>= 1) {
		sum += (lunarInfo[y - 1900] & i) ? 1 : 0;
	}
	return (sum + leapDays(y));
}

//返回农历年月日
function Lunar(objDate: Date) {
	let i, leap = 0, temp = 0;
	let offset = (Date.UTC(objDate.getFullYear(), objDate.getMonth() - 1, objDate.getDate()) - Date.UTC(1900, 0, 31)) / 86400000;
	for (i = 1900; i < 2100 && offset > 0; i++) {
		temp = lYearDays(i);
		offset -= temp;
	}
	if (offset < 0) {
		offset += temp;
		i--;
	}
	this.year = i;
	leap = leapMonth(i); // 闰哪个月
	this.isLeap = false;
	for (i = 1; i < 13 && offset > 0; i++) {
		// 闰月
		if (leap > 0 && i == (leap + 1) && this.isLeap == false) {
			--i;
			this.isLeap = true;
			temp = leapDays(this.year);
		} else {
			temp = monthDays(this.year, i);
		}
		// 解除闰月
		if (this.isLeap == true && i == (leap + 1)) {
			this.isLeap = false;
		}
		offset -= temp;
	}

	if (offset == 0 && leap > 0 && i == leap + 1) {
		if (this.isLeap) {
			this.isLeap = false;
		} else {
			this.isLeap = true;
			--i;
		}
	}
	if (offset < 0) {
		offset += temp;
		--i;
	}

	this.month = i;
	this.day = offset + 1;
}

//获取农历
function getLunarCalendar(year: number, month: string, day: string) {
	let FestivaLlist = { "0101": "春节", "0115": "元宵节", "0505": "端午节", "0707": "七夕情人节", "0715": "中元节", "0815": "中秋节", "0909": "重阳节", "1208": "腊八节", "1224": "小年" };
	let lDate = new Lunar(new Date(year, month, day));
	const property = `${strLength(lDate.month)}${strLength(lDate.day)}`
	return FestivaLlist[property] ? FestivaLlist[property] : ''
}
